package xworker.lang.task.flow;

import org.xmeta.ActionContext;
import org.xmeta.Thing;
import xworker.lang.actions.code.FakeGroovyAction;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class TaskFlowTaskActions {
    //xworker.lang.task.flow.TaskFlowTask/@actions/@getNextTasks
    public static List<TaskFlowTask> getNextTasks(ActionContext actionContext){
        List<TaskFlowTask> tasks = new ArrayList<>();
        Thing self = actionContext.getObject("self");
        TaskFlowTask task = actionContext.getObject("task");

        for(Thing taskThing : self.getChilds("TaskFlowTask")){
            tasks.add(new TaskFlowTask(taskThing, task));
        }

        return tasks;
    }

    public static List<TaskFlowTask> getOnSuccessNextTasks(ActionContext actionContext){
        List<TaskFlowTask> tasks = new ArrayList<>();
        Thing self = actionContext.getObject("self");
        TaskFlowTask task = actionContext.getObject("task");
        TaskFlowTask parentTask = task.getParentTask();
        if(parentTask == null || parentTask.isSuccess()) {
            for (Thing taskThing : self.getChilds("TaskFlowTask")) {
                tasks.add(new TaskFlowTask(taskThing, task));
            }
        }

        return tasks;

    }

    //xworker.lang.task.flow.OnException/@actions/@getNextTasks
    public static List<TaskFlowTask> getOnExceptionNextTasks(ActionContext actionContext){
        List<TaskFlowTask> tasks = new ArrayList<>();
        Thing self = actionContext.getObject("self");
        TaskFlowTask task = actionContext.getObject("task");
        TaskFlowTask parentTask = task.getParentTask();
        if(parentTask != null && !parentTask.isSuccess()) {
            for (Thing taskThing : self.getChilds("TaskFlowTask")) {
                tasks.add(new TaskFlowTask(taskThing, task));
            }
        }

        return tasks;
    }

    //xworker.lang.task.flow.Random/@actions/@getNextTasks
    public static List<TaskFlowTask> getRandomNextTasks(ActionContext actionContext){
        List<TaskFlowTask> tasks = new ArrayList<>();
        Thing self = actionContext.getObject("self");
        TaskFlowTask task = actionContext.getObject("task");
        int count = self.doAction("getMaxTaskCount", actionContext);
        if(count < 0){
            count = 1;
        }

        List<Thing> taskThings = new ArrayList<>(self.getChilds("TaskFlowTask"));
        Random random = new Random();
        if(count > 1){
            count = random.nextInt(count) + 1;
        }

        while(count > 0 && taskThings.size() > 0){
            int index = random.nextInt(taskThings.size());
            tasks.add(new TaskFlowTask(taskThings.get(index), task));
            taskThings.remove(index);
            count--;
        }

        return tasks;
    }
    //xworker.lang.task.flow.TaskFlowTask/@actions/@isReady
    public static boolean isReady(ActionContext actionContext){
        return true;
    }

    //xworker.lang.task.flow.Join/@actions/@isReady
    public static boolean isReadyJoin(ActionContext actionContext){
        Thing self = actionContext.getObject("self");
        List<String> preTasks = self.doAction("getPreTasks", actionContext);
        TaskFlowTask task = actionContext.getObject("task");
        boolean noException = self.getBoolean("noException");

        for(String peeTask : preTasks) {
            TaskFlowTask t = task.getTaskFlow().getTask(peeTask);
            if(t == null || !t.isFinished() || (noException && !t.isSuccess())){
                return false;
            }
        }

        return true;
    }

    //xworker.lang.task.flow.GroovyTask/@actions/@isReady
    public static Object isReadyGroovyTask(ActionContext actionContext){
        Thing self = actionContext.getObject("self");
        if(self.getStringBlankAsNull("isReadyCode") == null){
            return true;
        }

        return FakeGroovyAction.executeThingAttribute(self, "isReadyCode", actionContext);
    }

    //xworker.lang.task.flow.GroovyTask/@actions/@doTask
    public static Object doTaskGroovyAction(ActionContext actionContext){
        Thing self = actionContext.getObject("self");
        return FakeGroovyAction.executeThingAttribute(self, "doTaskCode", actionContext);
    }
}
